package m.toolkit.console;

import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author ming
 * @date 2014年2月22日下午9:55:31
 */
public class CommandPool {
	private static Logger log = LoggerFactory.getLogger(CommandPool.class);
	// 线程池
	private ThreadPoolExecutor threadPool;
	private CommandExecutorHolder commandHolder=new CommandExecutorHolder();

	public CommandPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
		threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
				handler);
	}
	
	public CommandPool(int corePoolSize ,int maximumPoolSize,int keepAliveTime,int seq) {
		TimeUnit unit = TimeUnit.SECONDS;
		BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(seq);
		threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
				noticeHandler);
	}

	public CommandPool() {
		int corePoolSize = CommandConfig.getCorePoolSize();
		int maximumPoolSize = CommandConfig.getMaximumPoolSize();
		int keepAliveTime = CommandConfig.getKeepAliveTime();
		TimeUnit unit = TimeUnit.SECONDS;
		BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(1);// 缓冲1个
		threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
				noticeHandler);
	}

	public void addCommand(Command command) {
		CommandExecutor cmdEx = new CommandExecutor(command);
		commandHolder.put(command.getCommandId(), cmdEx);
		threadPool.execute(cmdEx);
	}

	// 获取最新的执行结果
	public Command getOutput(String commandId,Long lastDataTime) {
		CommandExecutor cmdex = commandHolder.get(commandId);
		if(cmdex==null){
			return null;
		}
		Command command=cmdex.getCommand();
		if(command.getException()!=null){
			String error="执行命令["+command.getCommandContent()+"]失败,";
			command.setCurentOutput(error+"失败原因\n"+command.getException().getMessage());
			command.setLastUpdatetTime(command.getEndTime());
			return command;
		}
		
		
		Entry<Long,String> en= cmdex.getCommand().getOutputHolder().peek(lastDataTime);
		command.setCurentOutput(en.getValue());
		command.setLastUpdatetTime(en.getKey());
		return command;
	}
	
	//所能容纳的最大数
	public int maxSize(){
		return threadPool.getMaximumPoolSize();
	}
	
	//手动中止
	public void stop(String id) {
		CommandExecutor cmdex = commandHolder.get(id);
		if(cmdex!=null){
			cmdex.stop();
		}
	}

	private RejectedExecutionHandler noticeHandler = new RejectedExecutionHandler() {
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			CommandExecutor exe = (CommandExecutor) r;
			exe.cancel();
		}
	};// 如果线程满了,讲任务设置成取消

}
